#!/bin/env bash
#
# aim: install singal elasticsearch 5.8.9
# date: 10-13-2021
# elasticsearch 镜像下载地址下载连接地址 https://repo.huaweicloud.com/elasticsearch/6.8.5/elasticsearch-6.8.5.tar.gz
# version: 0.2
# author: li
# script: 此版本专用 elasticsearch-6.8.5
# 添加功能：
# 1. 增加认证


decompression_dir=/data
pkg_install_dir=/data/elasticsearch
pkg_name=elasticsearch-6.8.22
user_name=es
service_name=elasticsearch
service_port=(
    9200
    9300
)

for port in "${service_port[@]}";do
    portNum=`ss -ntpl | grep $port | wc -l`
    if [[ $portNum -gt 0 ]];then
        echo "tcp port ${port} already use try to other port !!!"
        exit 1
    fi
done

destroy_arg()
{
    unset decompression_dir
    unset pkg_install_dir
    unset pkg_name
    unset user_name
    unset service_name
    unset service_port
}

if [[  ! -f  "${pkg_name}.tar.gz" ]] ; then
    echo "${pkg_name}.tar.gz package is not exist"
    exit 1
fi
if [ ! -d "${decompression_dir}" ]; then
    mkdir -p ${decompression_dir}
fi

# install jdk
printf "\n<<<<<< install jdk \n"
type -p java >/dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "Java 已安装，版本信息如下："
    java -version
else
    # printf "\n<<<<<< install jdk \n"
    if [[  ! -f  "jdk-8u301-linux-x64.tar.gz" ]] ; then
        echo "jdk-8u301-linux-x64.tar.gz package is not exist"
        exit
    fi
    tar -xzf jdk-8u301-linux-x64.tar.gz -C ${decompression_dir}
echo "export JAVA_HOME=${decompression_dir}/jdk1.8.0_301
export JRE_HOME=${decompression_dir}/jdk1.8.0_301/jre
export CLASSPATH=.:\$JAVA_HOME/lib:\$JRE_HOME/lib:\$CLASSPATH
export PATH=\$JAVA_HOME/bin:\$JRE_HOME/bin:\$PATH" >> /etc/profile.d/jdk.sh
    source /etc/profile.d/jdk.sh
    java -version
    if [ $? -ne 0 ];then
        echo "install java fail"
        exit 1
    fi
fi

tar -xzf ${pkg_name}.tar.gz -C ${decompression_dir}
mv ${decompression_dir}/${pkg_name} ${pkg_install_dir}
mkdir ${pkg_install_dir}/data

if ! id -u ${user_name} >/dev/null 2>&1;then 
    useradd -M ${user_name} -s /sbin/nologin
fi
chown -R ${user_name}:${user_name} ${pkg_install_dir}

cp ${pkg_install_dir}/config/elasticsearch.yml ${pkg_install_dir}/config/elasticsearch_default.yml

#######   配置文件需要进行适当修改
cat << EOF > ${pkg_install_dir}/config/elasticsearch.yml
#索引数据的存储路径
path.data: ${pkg_install_dir}/data
#日志文件的存储路径
path.logs: ${pkg_install_dir}/logs
#设置为true来锁住内存。因为内存交换到磁盘对服务器性能来说是致命的，当jvm开始swapping时es的效率会降低，所以要保证它不swap
bootstrap.memory_lock: true
#绑定的ip地址 (可以填写本机ip或 0.0.0.0)
network.host: 0.0.0.0
#设置对外服务的http端口，默认为9200
http.port: ${service_port[0]}
#设置节点间交互的tcp端口,默认是9300
transport.tcp.port: ${service_port[1]}
#Elasticsearch将绑定到可用的环回地址，并将扫描端口9300到9305以尝试连接到运行在同一台服务器上的其他节点。
#这提供了自动集群体验，而无需进行任何配置。数组设置或逗号分隔的设置。每个值的形式应该是host:port或host
#（如果没有设置，port默认设置会transport.profiles.default.port 回落到transport.tcp.port）。

indices.fielddata.cache.size: 40%
EOF

echo "ELASTICSEARCH=${pkg_install_dir}
PATH=\$PATH:\$ELASTICSEARCH/bin
export ELASTICSEARCH PATH" > /etc/profile.d/es.sh
source /etc/profile.d/es.sh

printf "\n<<<<<< change kernal parameter \n"
cat << EOF >> /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
* soft memlock unlimited
* hard memlock unlimited
EOF

cat << EOF >> /etc/sysctl.conf
vm.max_map_count=262144
EOF

sysctl -p &> /dev/null

## 添加补丁
# rm -f ${pkg_install_dir}/modules/ingest-geoip/jackson-databind-2.8.11.3.jar
# cp jackson-databind-2.10.4.jar ${pkg_install_dir}/modules/ingest-geoip/
# chmod 777  ${pkg_install_dir}/modules/ingest-geoip/jackson-databind-2.10.4.jar


#### service 配置文件
cat << EOF > /usr/lib/systemd/system/$service_name.service
[Unit]
Description=$service_name
Requires=network.service
After=network.service

[Service]
User=$user_name
Group=$user_name
LimitNOFILE=65536
LimitMEMLOCK=infinity
Environment=JAVA_HOME=${decompression_dir}/jdk1.8.0_301
ExecStart=${pkg_install_dir}/bin/elasticsearch
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
SuccessExitStatus=143
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target
EOF


## es jvm 调优
availabel_memory=$(free -m | sed -n '2p'| awk '{print $2-$3}')
if [ ${availabel_memory} -lt 1024 ];then
    printf "<<<<<< the machine memory is not engouth for install elasticsearch ! at least 1GB"
    destroy_arg
    exit 1
fi

let availabel_memory=availabel_memory/1024/2
sed -i "s/-Xms1g/-Xms${availabel_memory}g/g" ${pkg_install_dir}/config/jvm.options
sed -i "s/-Xmx1g/-Xmx${availabel_memory}g/g" ${pkg_install_dir}/config/jvm.options

unset availabel_memory


systemctl daemon-reload
systemctl start ${service_name} --no-pager
systemctl enable ${service_name}

add_firewall()
{
    sed -i "s,<port protocol="tcp" port="9200"/>,<port protocol="tcp" port="${service_port[0]}"/>,g"s /usr/lib/firewalld/services/elasticsearch.xml 
    sed -i "s,<port protocol="tcp" port="9300"/>,<port protocol="tcp" port="${service_port[1]}"/>,g" /usr/lib/firewalld/services/elasticsearch.xml 
    printf "\n<<<<< add service to firewalld\n"
    firewall-cmd --permanent --add-service=elasticsearch
    printf "\n<<<<< reload firewalld\n"
    firewall-cmd --reload
}

prompt1="Start elasticsarch firewalld(y/n):"
while true; do
    read -p "$prompt1" yn
    case $yn in
        [Yy]* )
            systemctl |grep firewall|grep active &> /dev/null
            if [ $? -eq 0 ];then
                add_firewall
            else
                systemctl start firewall
                add_firewall
            fi
            break;;
        [Nn]* )
            break;;
        * )
            echo "!!! wrong input";;
    esac
done

sleep 30

printf "\n<<<<<< $service_name status \n"
systemctl status $service_name.service --no-pager

sleep 20

GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m'
host_ip=$(hostname -i)
service_status=$(curl -s -XGET "${host_ip}:9200/_cat/health?v" | awk '{print $4}' | tail -n +2)
text="<<<<<< $service_name node status: $service_status"
if [ "$service_status" = "green" ]; then
    colored_text="${text/green/${GREEN}green${NC}}"
elif [ "$service_status" = "red" ]; then
    colored_text="${text/red/${RED}red${NC}}"
elif [ "$service_status" = "yellow" ]; then
    colored_text="${text/yellow/${YELLOW}yellow${NC}}"
else
    colored_text="$service_status" # 默认为无色
fi
echo -e "$colored_text"

unset host_ip
unset service_status
sleep 10

function turn_on_auth(){
echo "xpack.security.enabled: true" >> ${pkg_install_dir}/config/elasticsearch.yml
echo "discovery.type: single-node" >> ${pkg_install_dir}/config/elasticsearch.yml
echo "xpack.license.self_generated.type: basic" >> ${pkg_install_dir}/config/elasticsearch.yml
echo "xpack.security.transport.ssl.enabled: true" >>  ${pkg_install_dir}/config/elasticsearch.yml
chown -R ${user_name}:${user_name} ${pkg_install_dir}
systemctl restart $service_name
sleep 10
${pkg_install_dir}/bin/elasticsearch-setup-passwords auto
}

prompt2="are you want to switch $service_name auth(y/n):"
while true; do
    read -p "$prompt2" yn
    case $yn in
        [Yy]* )
            printf "<<<<<< turn on elasticsearch auth ..."
            turn_on_auth
            break;;
        [Nn]* )

            break;;
        * )
            echo "!!! wrong input";;
    esac
done


destroy_arg